home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
-
- #include "DeskLib:GFX.h"
- #include "DeskLib:Coord.h"
- #include "DeskLib:WimpSWIs.h"
- #include "DeskLib:Error.h"
- #include "DeskLib:Window.h"
- #include "DeskLib:Event.h"
-
- #include "Shell.Extra.h"
- #include "Shell.SafeAlloc.h"
- #include "Shell.PlotIcon.h"
- #include "Shell.Redraw2.h"
-
-
-
- Shell_windblock Shell_windows[ Shell_MAXWINDS];
- int Shell_numwinds = 0;
-
-
-
-
-
-
-
-
- void Shell_WindRedraw2( wimp_rect *workrect, Shell_convertpoint convert, Shell_windblock *wind)
- /* This takes a workarea rectangle and redraws */
- /* any shell-rectangles in Shell window 'wind' */
- /* which overlap with it. */
- {
- Shell_rectblock *rectblock;
-
- for (
- rectblock = LinkList_FirstItem( &wind->anchor);
- rectblock;
- rectblock = LinkList_NextItem( &rectblock->header)
- )
-
- {
- if ( rectblock->plot_icon) {
- /* The rect should be plotted as an icon - e.g. for a border, and a */
- /* background colour. Also, we will set the grapics colour to the icon */
- /* foreground colour here. */
-
- if ( Coord_RectsOverlap( workrect, &rectblock->icon.workarearect))
- Shell_PlotIcon( &rectblock->icon, convert);
- /* Shell_PlotIcon is identical to Wimp_PlotIcon, but */
- /* only sends 16 bit coors to Wimp_PlotIcon, so arbitarily */
- /* sized icons can be plotted */
-
- Wimp_SetColour( rectblock->icon.flags.data.foreground);
-
- }
-
- if ( Coord_RectsOverlap( workrect, &rectblock->rect)) {
-
- /* Set things up so the redrawer only has to work in coors relative */
- /* to this rectblock's origin. */
-
- Shell_convertpoint localconvert;
- wimp_rect localredrawrect;
- wimp_point localsize;
-
- localsize.x = rectblock->rect.max.x - rectblock->rect.min.x;
- localsize.y = rectblock->rect.max.y - rectblock->rect.min.y;
-
- localconvert.x = convert.x + rectblock->rect.min.x;
- localconvert.y = convert.y + rectblock->rect.min.y;
-
- localredrawrect.min.x = workrect->min.x - rectblock->rect.min.x;
- localredrawrect.max.x = workrect->max.x - rectblock->rect.min.x;
- localredrawrect.min.y = workrect->min.y - rectblock->rect.min.y;
- localredrawrect.max.y = workrect->max.y - rectblock->rect.min.y;
-
- (*rectblock->redrawer)
- (
- localconvert,
- localsize,
- rectblock->reference,
- &localredrawrect
- );
- }
- }
-
- return;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- static BOOL Shell_WindRedraw( event_pollblock *event, void *reference)
-
- { Shell_windblock *info = (Shell_windblock *) reference;
- Shell_convertpoint convert;
- wimp_rect workrect;
- window_redrawblock redrawblock;
- BOOL more;
-
- redrawblock.window = event->data.openblock.window;
- Wimp_RedrawWindow( &redrawblock, &more);
-
- convert.x = redrawblock.rect.min.x - redrawblock.scroll.x;
- convert.y = redrawblock.rect.max.y - redrawblock.scroll.y;
-
- for (
- ;
- more;
- Wimp_GetRectangle( &redrawblock, &more)
- )
-
- {
- workrect = redrawblock.cliprect;
- Shell_ConvertRectToWorkarea( &workrect, convert);
-
- Shell_WindRedraw2( &workrect, convert, info);
- /* Most of the work is in this separate fn so that it can be called */
- /* independantly within a fn which temporaraly redirects output to a */
- /* sprite - see PlainRect.c */
-
- }
-
- return TRUE;
- }
-
-
-
-
-
-
-
-
-
- Shell_windblock *Shell_OpenWindow( void)
- {
- Shell_windblock *info;
-
- if ( Shell_numwinds == Shell_MAXWINDS) Error_ReportFatal( 1, Error_PLACE "Too many GFX windows");
- /* Should change the window storage to use a linked list (like each window's rect-list. */
-
- Shell_numwinds++;
- info = &Shell_windows[Shell_numwinds-1];
- info->window = Window_CreateAndShow( "ShellWindow", /*maxtitlesize*/ 0, open_NEARLAST);
-
- if ( info->window == 0)
- Error_ReportFatal( 0, Error_PLACE "Shell_OpenGFXWindow -couldn't find 'ShellWindow' in templates");
- /* This error-detection doesn't work - Window_CreateShow returns a non-zero window */
- /* handle even if the templates don't have the window. This can cause problems! */
-
- info->numrects = 0;
- LinkList_Init( &info->anchor);
-
- Event_Claim( event_REDRAW, info->window, event_ANY, Shell_WindRedraw, (void *) info);
-
- return info;
- }
-
-
-
-
-
-
-
- Shell_rectblock *Shell_AddRectangle(
- Shell_windblock *w,
- const wimp_rect *rect,
- Shell_redrawer redrawfn,
- const void *reference
- )
- /* This creates a 'plain' rectangle in a window - it has no border, and the background colour */
- /* will be the same as the background of the window. To give the rect a border and back/fore- */
- /* colours, use Shell_MakeRectIcon. */
-
- {
- Shell_rectblock *r;
-
- if ( (w-Shell_windows >= Shell_MAXWINDS) || (w-Shell_windows < 0))
- Error_ReportFatal( 1, Error_PLACE "Invalid Shell_windblock in Shell_AddRectangle, '%p'", w);
-
- w->numrects++;
- r = Shell_SafeMalloc( sizeof( Shell_rectblock));
- LinkList_AddToTail( &w->anchor, &r->header);
-
- r->update_time = 0; /* minimum time between rect redraws */
- r->last_update = 0;
- r->rect = *rect; /* rectangle which encloses the rect's data */
- r->icon.workarearect = *rect; /* border around the rect. */
- r->redrawer = redrawfn;
- r->saver = NULL; /* NULL or a valid rect saver */
- r->ramsaver = NULL; /* NULL or a valid rect ramsaver */
- r->size = 256; /* Default size. */
- r->filetype = 0xfff; /* Default filetype is text. */
- r->reference = (void *) reference;
- r->window = w->window;
- r->plot_icon = FALSE; /* This is a plain rect. */
-
-
- Shell_CheckWindSizeAndRedraw( w->window, &r->rect);
- /* This resizes the window if nesesary so that it contains the */
- /* rectangle. Hence the window automatically expands to contain */
- /* any rects added to it. */
-
- return r;
- }
-
-
-
-
-
- Shell_rectblock *Shell_AddRectangle2(
- Shell_windblock *w,
- int xmin, int ymin, int xmax, int ymax,
- Shell_redrawer redrawfn,
- const void *reference
- )
- {
- wimp_rect rect;
-
- rect.min.x = xmin; rect.min.y = ymin;
- rect.max.x = xmax; rect.max.y = ymax;
- return Shell_AddRectangle( w, &rect, redrawfn, reference);
- }
-
-
-
-
- Shell_rectblock *Shell_AddRectangle3(
- Shell_windblock *w,
- int xmin, int ymin,
- int xsize, int ysize,
- Shell_redrawer redrawfn,
- const void *reference
- )
- {
- wimp_rect rect;
-
- rect.min.x = xmin; rect.max.x = xmin + xsize;
- rect.min.y = ymin; rect.max.y = ymin + ysize;
- return Shell_AddRectangle( w, &rect, redrawfn, reference);
- }
-
-
-
-
-
-
- void Shell_ForceRectRedraw( Shell_rectblock *r)
- { window_redrawblock block;
- r->last_update = clock();
- block.window = r->window;
- block.rect = r->rect;
- Wimp_ForceRedraw( &block); /* The actual redraw will be done when the Wimp sends */
- /* event_REDRAW on the next Shell/Event_Poll. */
- return;
- }
-
-
- void Shell_ForceRectRedrawSlow( Shell_rectblock *r)
- /* This only ForceRedraws a rectangle if the */
- /* last redraw was a sufficiently long time ago */
- {
- clock_t t = clock();
- if ( t - r->last_update >= r->update_time) {
- r->last_update = t;
- Shell_ForceRectRedraw( r);
- }
- return;
- }
-
-
-
-
-
- void Shell_ForceRectUpdate( Shell_rectblock *r)
- /* This routine redraws a rectangle without clearing it */
- /* to the background colour. Use for animation etc. */
- /* The redraw loop occurs imediately, without polling */
- /* the Wimp. */
- {
- window_redrawblock redrawblock;
- Shell_convertpoint convert;
- wimp_rect workrect;
- BOOL more;
- wimp_point rectsize;
-
- rectsize.x = r->rect.max.x - r->rect.min.x;
- rectsize.y = r->rect.max.y - r->rect.min.y;
-
- redrawblock.window = r->window;
- redrawblock.rect = r->rect;
-
- Wimp_UpdateWindow( &redrawblock, &more);
-
- convert.x = redrawblock.rect.min.x - redrawblock.scroll.x + r->rect.min.x;
- convert.y = redrawblock.rect.max.y - redrawblock.scroll.y + r->rect.min.y;
-
-
- for (
- ;
- more;
- Wimp_GetRectangle( &redrawblock, &more)
- )
-
- {
- workrect.max.x = redrawblock.cliprect.max.x - convert.x;
- workrect.min.x = redrawblock.cliprect.min.x - convert.x;
- workrect.max.y = redrawblock.cliprect.max.y - convert.y;
- workrect.min.y = redrawblock.cliprect.min.y - convert.y;
-
- ( *(r->redrawer) ) ( convert, rectsize, r->reference, &workrect);
- /* Call the redrawing function for the rectangle */
-
- }
- }
-
-
-
-
- void Shell_ForceRectUpdateSlow( Shell_rectblock *r)
- /* This only ForceUpdates a rectangle if the */
- /* last redraw was a sufficiently long time ago */
- {
- clock_t t = clock();
- if ( t - r->last_update >= r->update_time) {
- r->last_update = t;
- Shell_ForceRectUpdate( r);
- }
- return;
- }
-
-
-
-
-
- void Shell_SetWindowTitle( window_handle window, char *text)
- /* There used to be code here, but DeskLib 2.04 has a function built in which actually */
- /* works properly! */
- {
- Window_SetTitle( window, text);
- }
-